package com.tanhua.manage.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.common.mapper.AnalysisByDayMapper;
import com.tanhua.common.mapper.RetentionldMapper;
import com.tanhua.common.pojo.AnalysisByDay;
import com.tanhua.manage.pojo.Distribution;
import com.tanhua.manage.vo.*;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.text.DecimalFormat;
import java.util.*;

/**
 * @author Ling
 * @Title: null.java
 * @Package com.tanhua.manage.service
 * @Description:
 * @date 2021/9/11 16:29
 */
@Service
@Slf4j
public class DashboardService {

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private UserService userService;

    @Autowired
    private RetentionldService retentionldService;

    @Autowired
    private AnalysisByDayService analysisByDayService;


    private final static String[] HUA_BEI = {"北京市", "天津市", "河北省", "山西省", "内蒙古"};
    private static Integer HUA_BEI_COUNT = 0;
    private final static String[] HUA_NAN = {"广东省", "广西", "海南省", "香港", "澳门"};
    private static Integer HUA_NAN_COUNT = 0;
    private final static String[] HUA_ZHONG = {"河南省", "湖北省", "湖南省"};
    private static Integer HUA_ZHONG_COUNT = 0;
    private final static String[] DONG_BEI = {"黑龙江省", "吉林省", "辽宁省"};
    private static Integer DONG_BEI_COUNT = 0;
    private final static String[] HUA_DONG = {"上海市", "江苏省", "浙江省", "安徽省", "江西省", "山东省", "福建省", "台湾省"};
    private static Integer HUA_DONG_COUNT = 0;
    private final static String[] XI_NAN = {"重庆市", "四川省", "贵州省", "云南省", "西藏"};
    private static Integer XI_NAN_COUNT = 0;
    private final static String[] XI_BEI = {"陕西省", "甘肃省", "青海省", "宁夏", "新疆"};
    private static Integer XI_BEI_COUNT = 0;


    public DistributionVo getDistribution(Long sd, Long ed) {
        initCount();
        DistributionVo distributionVo = new DistributionVo();
        Date start = new Date(sd);
        Date end = new Date(ed);
//        String start1 = DateUtil.formatDateTime(start);
//        String end1 = DateUtil.formatDateTime(end);

        List<Distribution> ageDistribution = new ArrayList<>();
        List<Map<String, Object>> age = userInfoService.countAgeDistribution(start, end);
        for (Map<String, Object> stringObjectMap : age) {
            Distribution distribution = new Distribution();
            distribution.setTitle(stringObjectMap.get("agegroup").toString());
            distribution.setAmount((Convert.toInt(stringObjectMap.get("count"))));
            ageDistribution.add(distribution);
        }


        List<Map<String, Object>> gender = userInfoService.countGenderDistribution(start, end);
//        List<Map<String, Object>> maps1 = userInfoService.countIndustryDistribution(start1, end1);

        List<Distribution> genderDistribution = new ArrayList<>();
        for (Map<String, Object> map : gender) {
            Distribution distribution = new Distribution();
            distribution.setTitle(Convert.toInt(map.get("sex")) == 1 ? "男" : "女");
            distribution.setAmount((Convert.toInt(map.get("count"))));
            genderDistribution.add(distribution);
        }

        List<Map<String, Object>> industry = userInfoService.countIndustryDistribution(start, end);
        List<Distribution> industryDistribution = new ArrayList<>();
        for (Map<String, Object> map : industry) {
            Distribution distribution = new Distribution();
            distribution.setTitle(map.get("industry").toString());
            distribution.setAmount((Convert.toInt(map.get("count"))));
            industryDistribution.add(distribution);
        }
        List<Map<String, Object>> location = userInfoService.countLocalDistribution(start, end);
        List<Distribution> locationDistribution = new ArrayList<>();
        for (Map<String, Object> map : location) {
            Distribution distribution = new Distribution();
            String city = map.get("city").toString();
            distribution.setTitle(city);
            Integer count = Convert.toInt(map.get("count"));
            distribution.setAmount(count);
            this.setLocalTotalCount(city, count);
            locationDistribution.add(distribution);
        }

        distributionVo.setAgeDistribution(ageDistribution);
        distributionVo.setLocalDistribution(locationDistribution);
        distributionVo.setGenderDistribution(genderDistribution);
        distributionVo.setIndustryDistribution(industryDistribution);
        distributionVo.setLocalTotal(getLocalTotal());


        return distributionVo;
    }

    private void initCount() {
        HUA_BEI_COUNT = 0;
        HUA_NAN_COUNT = 0;
        HUA_ZHONG_COUNT = 0;
        DONG_BEI_COUNT = 0;
        HUA_DONG_COUNT = 0;
        XI_NAN_COUNT = 0;
        XI_BEI_COUNT = 0;
    }

    private void setLocalTotalCount(String city, Integer count) {
        ArrayList<String> huabei = CollUtil.toList(HUA_BEI);
        ArrayList<String> huanan = CollUtil.toList(HUA_NAN);
        ArrayList<String> huadong = CollUtil.toList(HUA_DONG);
        ArrayList<String> huazhong = CollUtil.toList(HUA_ZHONG);
        ArrayList<String> dongbei = CollUtil.toList(DONG_BEI);
        ArrayList<String> xibei = CollUtil.toList(XI_BEI);
        ArrayList<String> xinan = CollUtil.toList(XI_NAN);

        if (huabei.contains(city)) {
            HUA_BEI_COUNT += count;
        } else if (huanan.contains(city)) {
            HUA_NAN_COUNT += count;
        } else if (huadong.contains(city)) {
            HUA_DONG_COUNT += count;
        } else if (huazhong.contains(city)) {
            HUA_ZHONG_COUNT += count;
        } else if (dongbei.contains(city)) {
            DONG_BEI_COUNT += count;
        } else if (xibei.contains(city)) {
            XI_BEI_COUNT += count;
        } else if (xinan.contains(city)) {
            XI_NAN_COUNT += count;
        }

    }

    private List<Distribution> getLocalTotal() {
        List<Distribution> localTotal = new ArrayList<>();
        localTotal.add(new Distribution("华北地区", HUA_BEI_COUNT));
        localTotal.add(new Distribution("华南地区", HUA_NAN_COUNT));
        localTotal.add(new Distribution("华中地区", HUA_ZHONG_COUNT));
        localTotal.add(new Distribution("东北地区", DONG_BEI_COUNT));
        localTotal.add(new Distribution("华东地区", HUA_DONG_COUNT));
        localTotal.add(new Distribution("西北地区", XI_BEI_COUNT));
        localTotal.add(new Distribution("西南地区", XI_NAN_COUNT));
        return localTotal;
    }

    public SummaryVo getSummary() {
        SummaryVo summaryVo = new SummaryVo();
        try {
            summaryVo.setCumulativeUsers(userService.queryUserCount());
            List<AnalysisByDayVo> passWeeks = analysisByDayService.queryDayByDate(DateUtil.offsetWeek(new Date(), -1).getTime(), System.currentTimeMillis());
            Integer countpassWeek = 0;
            for (AnalysisByDayVo passWeek : passWeeks) {
                countpassWeek += passWeek.getNumActive();
            }
            List<AnalysisByDayVo> passMonths = analysisByDayService.queryDayByDate(DateUtil.offsetMonth(new Date(), -1).getTime(), System.currentTimeMillis());
            Integer countPassMonth = 0;
            for (AnalysisByDayVo passMonth : passMonths) {
                countPassMonth += passMonth.getNumActive();
            }

//            summaryVo.setActivePassMonth(analysisByDayService.QueryActivePassTime(DateUtil.lastMonth()));
            summaryVo.setActivePassMonth(countPassMonth);
//            summaryVo.setActivePassWeek(analysisByDayService.QueryActivePassTime(DateUtil.lastWeek()));
            summaryVo.setActivePassWeek(countpassWeek);


//            AnalysisByDay today = analysisByDayService.queryAnalysisToDay();
            List<AnalysisByDayVo> todays = analysisByDayService.queryDayByDate(System.currentTimeMillis(), System.currentTimeMillis());
            AnalysisByDayVo today = todays.get(0);
            summaryVo.setNewUsersToday(today.getNumRegistered());
            summaryVo.setLoginTimesToday(today.getNumLogin());
            summaryVo.setActiveUsersToday(today.getNumActive());

//            AnalysisByDay yesterday = analysisByDayService.queryAnalysisYesterday(new Date());
            long yesterdayMill = DateUtil.offsetDay(new Date(), -1).getTime();
            List<AnalysisByDayVo> yesterdayAnalysisByDayVos = analysisByDayService.queryDayByDate(yesterdayMill, yesterdayMill);

            AnalysisByDayVo yesterday = yesterdayAnalysisByDayVos.get(0);

            long theDayBeforeYesterdayMill = DateUtil.offsetDay(new Date(), -2).getTime();
//            AnalysisByDay theDayBeforeYesterday = analysisByDayService.queryAnalysisYesterday(DateUtil.yesterday());
            List<AnalysisByDayVo> tDBYAnal = analysisByDayService.queryDayByDate(theDayBeforeYesterdayMill, theDayBeforeYesterdayMill);
            AnalysisByDayVo theDayBeforeYesterday = tDBYAnal.get(0);

            summaryVo.setActiveUsersYesterday(yesterday.getNumActive());

            //环比计算（本期数-上期数）/上期数×100%
            summaryVo.setNewUsersTodayRate(getPercent(today.getNumRegistered() - yesterday.getNumRegistered(), yesterday.getNumRegistered()));
            summaryVo.setLoginTimesTodayRate(getPercent(today.getNumLogin() - yesterday.getNumLogin(), yesterday.getNumLogin()));
            summaryVo.setActiveUsersTodayRate(getPercent(today.getNumActive() - yesterday.getNumActive(), yesterday.getNumActive()));
            summaryVo.setActiveUsersYesterdayRate(getPercent(yesterday.getNumActive() - theDayBeforeYesterday.getNumActive(), theDayBeforeYesterday.getNumActive()));
            return summaryVo;

        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    private String getPercent2(Integer x, Integer y) {
        double d1 = x * 1.0;
        double d2 = y * 1.0;
        DecimalFormat decimalFormat = new DecimalFormat("##.0000%");
        return decimalFormat.format(d1 / d2);
    }

    private Double getPercent(Integer x, Integer y) {
        double d1 = x * 1.0;
        double d2 = y * 1.0;
        return d1 / d2 * 100D;
    }

    public UsersDistributionVo getUsers(Long sd, Long ed, String type) {
        //todo 等待代码
//        List<RetentionldVo> retentionldVosThisyear = retentionldService.queryCheck(sd, ed);
//        List<RetentionldVo> retentionldVosLastyear = retentionldService.queryCheck(sd, ed);
        List<AnalysisByDayVo> analysisByDayVosThisyear = analysisByDayService.queryDayByDate(sd, ed);
        List<AnalysisByDayVo> analysisByDayVosLastyear = analysisByDayService.queryDayByDate(DateUtil.offsetMonth(new Date(sd), -12).getTime(), DateUtil.offsetMonth(new Date(ed), -12).getTime());


        List<Distribution> thisyear = new ArrayList<>();
        List<Distribution> lastyear = new ArrayList<>();
        if (StrUtil.equals(type, "101")) {
            for (AnalysisByDayVo analysisByDayVo : analysisByDayVosThisyear) {
                Distribution distribution = new Distribution();
                distribution.setTitle(analysisByDayVo.getRecordDate());
                distribution.setAmount(analysisByDayVo.getNumRegistered());
                thisyear.add(distribution);
            }
            for (AnalysisByDayVo analysisByDayVo : analysisByDayVosLastyear) {
                Distribution distribution = new Distribution();
                distribution.setTitle(analysisByDayVo.getRecordDate());
                distribution.setAmount(analysisByDayVo.getNumRegistered());
                lastyear.add(distribution);
            }
        }
        if (StrUtil.equals(type, "102")) {
            for (AnalysisByDayVo analysisByDayVo : analysisByDayVosThisyear) {
                Distribution distribution = new Distribution();
                distribution.setTitle(analysisByDayVo.getRecordDate());
                distribution.setAmount(analysisByDayVo.getNumActive());
                thisyear.add(distribution);
            }
            for (AnalysisByDayVo analysisByDayVo : analysisByDayVosLastyear) {
                Distribution distribution = new Distribution();
                distribution.setTitle(analysisByDayVo.getRecordDate());
                distribution.setAmount(analysisByDayVo.getNumActive());
                lastyear.add(distribution);
            }
        }
        if (StrUtil.equals(type, "103")) {
            for (AnalysisByDayVo analysisByDayVo : analysisByDayVosThisyear) {
                Distribution distribution = new Distribution();
                distribution.setTitle(analysisByDayVo.getRecordDate());
                distribution.setAmount(analysisByDayVo.getNumRetention1d());
                thisyear.add(distribution);
            }
            for (AnalysisByDayVo analysisByDayVo : analysisByDayVosLastyear) {
                Distribution distribution = new Distribution();
                distribution.setTitle(analysisByDayVo.getRecordDate());
                distribution.setAmount(analysisByDayVo.getNumRetention1d());
                lastyear.add(distribution);
            }
        }
        UsersDistributionVo usersDistributionVo = new UsersDistributionVo();
        usersDistributionVo.setThisYear(thisyear);
        usersDistributionVo.setLastYear(lastyear);
        return usersDistributionVo;
    }
}
